/*
 * ULSF Sagittarius IDA Jones Panel
 * Copyright (C) 2002, Kevin Jones, all rights reserved.
 * Copyright (C) 2012, John Pritchard, all rights reserved.
 * 
 * This program is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see
 * <http://www.gnu.org/licenses/>.
 */
package sagittarius.panel;

public class NACA
    extends Airfoil
{

    private final static class Foil {

        float xc, tc, yc, beta;
    }

    public final int naca, naca_45, naca_3, naca_12;

    public final float c_max, x_cam, t_max;


    public NACA(Panel p){
        super();
        if (p.isNACA()){
            this.naca = p.inputs.naca;

            this.naca_45 = this.naca / 1000;
            this.naca_3  = this.naca / 100 - 10 * this.naca_45;
            this.naca_12 = this.naca - 1000 * this.naca_45 - 100 * this.naca_3;

            float c_max = this.naca_45 * 0.01f;
            float x_cam = this.naca_3  * 0.1f;
            float t_max = this.naca_12 * 0.01f;

            if (10 <= this.naca_45){
                switch (this.naca_45){
                case 21:
                    c_max = 0.0580f;
                    x_cam = 361.4f * (float)Math.pow(c_max,3) / 6;
                    break;
                case 22:
                    c_max = 0.1260f;
                    x_cam = 51.64f * (float)Math.pow(c_max,3) / 6;
                    break;
                case 23:
                    c_max = 0.2025f;
                    x_cam = 15.957f * (float)Math.pow(c_max,3) / 6;
                    break;
                case 24:
                    c_max = 0.2900f;
                    x_cam = 6.643f * (float)Math.pow(c_max,3) / 6;
                    break;
                default:
                    c_max = 0.3910f;
                    x_cam = 3.230f * (float)Math.pow(c_max,3) / 6;
                    break;
                }
            }
            this.c_max = c_max;
            this.x_cam = x_cam;
            this.t_max = t_max;

            Foil foil = new Foil();
            
            final int npoints = p.surface.npoints;
            final int nle = p.surface.nle;
            final boolean not5 = (naca < 9999);
            int nlower, nupper;
            float dtx, dty, xb[] = p.surface.xb, yb[] = p.surface.yb;

            for (int n = 1, z = (nle-1); n < z; n++){

                foil.xc = ( 1 + (float)Math.cos( (float)Math.PI * (n-1)/(nle-1) )) / 2;
                nlower = n;
                nupper = npoints + 1 - n;

                NACA.XY45(not5,t_max,c_max,x_cam,foil);

                dtx = foil.tc * (float)Math.sin( foil.beta );
                dty = foil.tc * (float)Math.cos( foil.beta );
                xb[nlower-1] = foil.xc + dtx;
                yb[nlower-1] = foil.yc - dty;
                xb[nupper-1] = foil.xc - dtx;
                yb[nupper-1] = foil.yc + dty;
            }

            xb[0] = 1.0f;
            yb[0] = 0.0f;
            xb[nle-1] = 0.0f;
            yb[nle-1] = 0.0f;
            xb[npoints-1] = xb[0];
            yb[npoints-1] = yb[0];

            if (naca > 9999)
                p.consts.title = String.format("NACA %5d",naca);
            else
                p.consts.title = String.format("NACA %4d",naca);
        }
        else
            throw new IllegalArgumentException();
    }

    private final static void XY45(final boolean naca, final float t_max, final float m, final float p, 
                                   Foil foil)
    {

        if ( foil.xc < 1.0e-10 ){
            foil.tc = 0.0f;
        }
        else {
            foil.tc = t_max * 5 * ( 0.2969f * (float)Math.sqrt(foil.xc)
                                    - foil.xc * ( 0.1260f
                                                  + foil.xc * ( 0.3537f
                                                                - foil.xc * ( 0.2843f
                                                                              - foil.xc * 0.1015f))));
        }

        if ( 0.0 == m){
            foil.yc = 0.0f;
            foil.beta = 0.0f;
        }
        else {
            float r;
            if (naca){
                r = foil.xc / p;
                if ( foil.xc < p ){
                    foil.yc   = 2 * m * r - m * (r*r);
                    foil.beta = (float)Math.atan( 2 * m * ( 1 - r ) / p );
                }
                else {
                    foil.yc   = m*(p*p)/(float)Math.pow((1-p),2) * ((1-2*p)/(p*p) + 2*r - (r*r) );
                    foil.beta = (float)Math.atan( 2*p*m/Math.pow((1-p),2) * ( 1-r));
                }
            }
            else {
                r = foil.xc / m;
                if ( foil.xc < m ){
                    foil.yc   = p * ( (float)Math.pow(r,3) - 3*(r*r) + (3-m)*r );
                    foil.beta = (float)Math.atan( p/m * ( 3*(r*r) - 6*r + 3 - m ));
                }
                else {
                    foil.yc   = p * ( 1.0f - foil.xc );
                    foil.beta = (float)Math.atan( -p );
                }
            }
        }
    }

}
